package com.wusiwei.util;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.UUID;

/**
 * 阿里云OSS工具类
 */
@Component
@Slf4j
public class AliOssUtil {

    //已经正确填写阿里云配置，无需修改
    private static String ENDPOINT;
    private static String ACCESS_KEY_ID;
    private static String ACCESS_KEY_SECRET;
    private static String BUCK_NAME;

    /**
     * 上传文件到OSS
     *
     * @param objectName  对象名称
     * @param inputStream 输入流
     * @return 文件访问URL
     */
    public static String uploadFile(String objectName, InputStream inputStream) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

        String url = "";
        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(BUCK_NAME, objectName, inputStream);

            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            url = "https://" + BUCK_NAME + "." + ENDPOINT.substring(ENDPOINT.lastIndexOf("/") + 1) + "/" + objectName;
        } catch (OSSException oe) {
            log.error("OSS异常：请求到达OSS服务但被拒绝");
            log.error("错误消息：{}", oe.getErrorMessage());
            log.error("错误代码：{}", oe.getErrorCode());
            log.error("请求ID：{}", oe.getRequestId());
            log.error("主机ID：{}", oe.getHostId());
            throw oe;
        } catch (ClientException ce) {
            log.error("客户端异常：与OSS通信时出现严重的内部问题，如网络无法访问");
            log.error("错误消息：{}", ce.getMessage());
            throw ce;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return url;
    }

    /**
     * 上传文件到OSS
     *
     * @param file    文件对象
     * @param dirPath 存储目录，例如：invoice/
     * @return 文件访问URL
     * @throws Exception 异常
     */
    public static String uploadFile(MultipartFile file, String dirPath) throws Exception {
        // 文件原始名称
        String originalFilename = file.getOriginalFilename();
        // 文件扩展名
        String suffix = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        }

        // 使用年月组织目录，例如：invoice/2025-01/
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")) + "/";
        // 生成UUID作为文件名
        String fileName = UUID.randomUUID().toString() + suffix;
        // 完整的对象名称
        String objectName = dirPath + datePath + fileName;

        // 调用上传方法
        return uploadFile(objectName, file.getInputStream());
    }

    /**
     * 上传BASE64编码的图片到OSS
     *
     * @param base64Data BASE64编码的图片数据（不包含前缀如data:image/jpeg;base64,）
     * @param dirPath    存储目录，例如：invoice/
     * @return 文件访问URL
     * @throws Exception 异常
     */
    public static String uploadBase64Image(String base64Data, String dirPath) throws Exception {
        // 移除可能包含的Base64前缀
        if (base64Data.contains(",")) {
            base64Data = base64Data.substring(base64Data.indexOf(",") + 1);
        }

        // 解码Base64数据
        byte[] imageBytes = Base64.getDecoder().decode(base64Data);
        ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);

        // 使用年月组织目录
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")) + "/";
        // 生成随机文件名
        String fileName = UUID.randomUUID().toString() + ".jpg"; // 默认为jpg格式
        // 完整的对象名称
        String objectName = dirPath + datePath + fileName;

        // 调用上传方法
        return uploadFile(objectName, inputStream);
    }

    /**
     * 删除OSS中的文件
     *
     * @param fileUrl 文件URL
     * @return 是否删除成功
     */
    public static boolean deleteFile(String fileUrl) {
        if (StringUtil.isEmpty(fileUrl)) {
            return false;
        }

        try {
            // 从文件URL提取对象名称
            String objectName = null;

            // 尝试多种格式解析对象名称
            if (fileUrl.contains(BUCK_NAME + ".")) {
                // 格式: https://bucket-name.endpoint/object-name
                int index = fileUrl.indexOf(BUCK_NAME + ".");
                String temp = fileUrl.substring(index + BUCK_NAME.length() + 1);
                objectName = temp.substring(temp.indexOf("/") + 1);
            } else if (fileUrl.contains("/" + BUCK_NAME + "/")) {
                // 格式: https://endpoint/bucket-name/object-name
                objectName = fileUrl.substring(fileUrl.indexOf("/" + BUCK_NAME + "/") + BUCK_NAME.length() + 2);
            } else if (fileUrl.startsWith("http")) {
                // 简单解析，取URL的最后部分
                String[] parts = fileUrl.split("/");
                if (parts.length > 0) {
                    // 获取路径的最后两部分 (例如: yyyy-MM/filename.ext)
                    String datePath = parts[parts.length - 2];
                    String fileName = parts[parts.length - 1];

                    if (fileUrl.contains("/invoice/")) {
                        objectName = "invoice/" + datePath + "/" + fileName;
                    } else if (fileUrl.contains("/receipt/")) {
                        objectName = "receipt/" + datePath + "/" + fileName;
                    } else if (fileUrl.contains("/order/")) {
                        objectName = "order/" + datePath + "/" + fileName;
                    } else {
                        objectName = datePath + "/" + fileName;
                    }
                }
            }

            if (objectName == null) {
                log.warn("无法从URL解析对象名称: {}", fileUrl);
                return false;
            }

            log.info("从URL [{}] 解析的对象名称: {}", fileUrl, objectName);

            // 创建OSSClient实例
            OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

            try {
                // 检查文件是否存在
                if (!ossClient.doesObjectExist(BUCK_NAME, objectName)) {
                    log.warn("文件不存在: {}", objectName);
                    return false;
                }

                // 删除文件
                ossClient.deleteObject(BUCK_NAME, objectName);
                log.info("文件删除成功: {}", objectName);
                return true;
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        } catch (Exception e) {
            log.error("删除文件失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Value("${aliyun.oss.endpoint}")
    public void setEndpoint(String endpoint) {
        ENDPOINT = endpoint;
    }

    @Value("${aliyun.oss.access-key-id}")
    public void setAccessKeyId(String accessKeyId) {
        ACCESS_KEY_ID = accessKeyId;
    }

    @Value("${aliyun.oss.access-key-secret}")
    public void setAccessKeySecret(String accessKeySecret) {
        ACCESS_KEY_SECRET = accessKeySecret;
    }

    @Value("${aliyun.oss.bucket-name}")
    public void setBuckName(String buckName) {
        BUCK_NAME = buckName;
    }
}
